package com.androwit.engine;

import java.util.Map;

import com.androwit.engine.mapping.MappingField;
import com.androwit.engine.mapping.MappingFieldsDefiner;

/**
 * This interface handles the io bridge
 * 
 * @param <K>
 *          the type of the keys
 * @param <V>
 *          the type of the values in the storage layer
 * @author Zied Hamdi Founder of http://1vu.fr
 * 
 */
public interface MappingReader<K, V> {

	/**
	 * reads (consumes) the current record and sets the cursor to the next one.
	 * Works similarly as an iterator, but reads directly the first record if any
	 * 
	 * This method prepares the ground for {@link #getRelevantValues()} and
	 * {@link #get(MappingField)}
	 * 
	 * @return true if the record was read, false if the end is reached
	 */
	boolean readRecord();

	/**
	 * returns the relevant values to identify how to read the currently pointed
	 * cursor: since the library is designed to handle heterogeneous data, each
	 * row can have its own columns to be read to identify its nature.
	 * 
	 * The method {@link MappingFieldsDefiner#createInstance(Map)} uses the return
	 * value of this method to create the right instance that will contain the
	 * data.
	 * 
	 * The method {@link MappingFieldsDefiner#getMappedFields(Map)} is then
	 * responsible to inform about the fields that should be read.
	 * 
	 * Each field is read through the method {@link #get(MappingField)} and used
	 * to fill each property of the current cursor's representing instance.
	 * 
	 * @param fieldsDefiner
	 *          this is the object that defines the currently read data structure,
	 *          it may be asked of what columns are needed to be read
	 * 
	 * @return the string relevant values of the current row to identify
	 *         properties of the currently pointed cursor
	 */
	Map<K, V> getRelevantValues(MappingFieldsDefiner<?, K, V> fieldsDefiner);

	/**
	 * returns the value of the column <code>index</code>
	 * 
	 * @param field
	 *          column key
	 * @return value at key
	 */
	V get(MappingField<?, K, V> field);

}
